package com.laicunba.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.stereotype.Service;

import com.laicunba.pojo.CashCouponDO;
import com.laicunba.pojo.FinancingTargetBidDO;
import com.laicunba.pojo.FinancingTargetDO;
import com.laicunba.pojo.UserDO;
import com.laicunba.pojo.vo.CashCouponVO;
import com.laicunba.service.CashCouponService;
import com.laicunba.util.AssertUtil;
import com.laicunba.util.StringUtil;

@Service
public class CashCouponServiceImpl extends BaseServiceImpl implements CashCouponService {
	private static final Logger LOG = Logger.getLogger(CashCouponServiceImpl.class);

	@Override
	public List<CashCouponDO> findUseableCashCoupon(String userId) {
		return queryDao.selectList("CASH_COUPON.findUseableCashCoupon", userId);
	}

	@Override
	public boolean testForConditions(FinancingTargetBidDO bidDO, CashCouponDO cashCouponDO, FinancingTargetDO financingTargetDO) {
		AssertUtil.assertNotNull(cashCouponDO, "CASH_COUPON_NOT_EXIST");
		AssertUtil.assertTrue(StringUtil.isEmpty(cashCouponDO.getFinancingTargetBidId()), "CASH_COUPON_BID_ID_EXIST");
		// 是否已用?
		AssertUtil.assertTrue(cashCouponDO.getUsedAmount() == null || cashCouponDO.getUsedAmount().compareTo(BigDecimal.ZERO) == 0, "CASH_COUPON_IS_USED");
		// 是否该用户拥有?
		AssertUtil.assertTrue(bidDO.getBidUserId().equals(cashCouponDO.getUserId()), "CASH_COUPON_USERID_ERROR");
		AssertUtil.assertNotNull(cashCouponDO.getBeginTime(), "CASH_COUPON_HAS_NO_BEGIN_TIME");
		AssertUtil.assertNotNull(cashCouponDO.getEndTime(), "CASH_COUPON_HAS_NO_END_TIME");

		// 是否过有效期?
		Date now = new Date();
		AssertUtil.assertTrue(cashCouponDO.getBeginTime().before(now) && cashCouponDO.getEndTime().after(now), "CASH_COUPON_VALID_ERROR");

		// 加息标，不能使用
		AssertUtil.assertTrue(financingTargetDO.getIncrRate() == null || financingTargetDO.getIncrRate().compareTo(BigDecimal.ZERO) == 0, "CANT_USE_CASH_COUPON");
		AssertUtil.assertTrue(!financingTargetDO.getName().contains("加息"), "CANT_USE_CASH_COUPON");

		// 检查使用条件
		if (StringUtil.isEmpty(cashCouponDO.getConditions())) {
			return true;
		}

		// [{"period":30,"buy_amount":1000}]
		try {
			String errorCode = "";
			JSONArray conditions = (JSONArray) new JSONParser().parse(cashCouponDO.getConditions());
			for (int i = 0; i < conditions.size(); i++) {
				JSONObject condition = (JSONObject) conditions.get(i);
				errorCode = "";
				// 满N元?
				if (condition.containsKey("buy_amount")) {
					if (bidDO.getBuyAmount().compareTo(new BigDecimal(condition.get("buy_amount").toString())) < 0) {
						errorCode = "BUY_AMOUNT_CONDITION_ERROR";
					}
				}
				// 满N天?
				if (condition.containsKey("period")) {
					if (financingTargetDO.getPeriod() < Integer.parseInt(condition.get("period").toString())) {
						errorCode = "PERIOD_CONDITION_ERROR";
					}
				}
				// 定标还是活标?
				if (condition.containsKey("target_type")) {
					if (!bidDO.getType().equalsIgnoreCase(condition.get("target_type").toString())) {
						errorCode = "TARGET_TYPE_CONDITION_ERROR";
					}
				}

				if (StringUtil.isEmpty(errorCode)) {
					return true;
				}

			}

			if (StringUtil.isNotEmpty(errorCode)) {
				AssertUtil.assertFail(errorCode);
			}

		} catch (ParseException e) {
			LOG.error("现金券条件解释出错:" + cashCouponDO.getConditions(), e);
			return false;
		}

		return true;
	}

	@Override
	public List<CashCouponDO> findCashCoupons(String userId) {
		return queryDao.selectList("CASH_COUPON.findCashCoupons", userId);
	}

	@Override
	public List<CashCouponVO> findCashCouponVOs(String userId) {
		return queryDao.selectList("CASH_COUPON.findCashCouponVOs", userId);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public List<UserDO> findNoSendUsers(String userType, String couponDefId, int limit) {
		Map map = new HashMap();
		map.put("couponDefId", couponDefId);
		map.put("limit", limit);
		return queryDao.selectList("CASH_COUPON.".concat(userType), map);
	}

	@Override
	public boolean testForConditions(CashCouponDO cashCouponDO, UserDO buyer, FinancingTargetDO financingTargetDO, BigDecimal buyAmt) {
		AssertUtil.assertNotNull(cashCouponDO, "CASH_COUPON_NOT_EXIST");
		AssertUtil.assertTrue(StringUtil.isEmpty(cashCouponDO.getFinancingTargetBidId()), "CASH_COUPON_BID_ID_EXIST");
		// 是否已用?
		AssertUtil.assertTrue(cashCouponDO.getUsedAmount() == null || cashCouponDO.getUsedAmount().compareTo(BigDecimal.ZERO) == 0, "CASH_COUPON_IS_USED");
		// 是否该用户拥有?
		AssertUtil.assertTrue(buyer.getId().equals(cashCouponDO.getUserId()), "CASH_COUPON_USERID_ERROR");
		AssertUtil.assertNotNull(cashCouponDO.getBeginTime(), "CASH_COUPON_HAS_NO_BEGIN_TIME");
		AssertUtil.assertNotNull(cashCouponDO.getEndTime(), "CASH_COUPON_HAS_NO_END_TIME");

		// 是否过有效期?
		Date now = new Date();
		AssertUtil.assertTrue(cashCouponDO.getBeginTime().before(now) && cashCouponDO.getEndTime().after(now), "CASH_COUPON_VALID_ERROR");

		// 加息标，不能使用
		AssertUtil.assertTrue(financingTargetDO.getIncrRate() == null || financingTargetDO.getIncrRate().compareTo(BigDecimal.ZERO) == 0, "CANT_USE_CASH_COUPON");
		AssertUtil.assertTrue(!financingTargetDO.getName().contains("加息"), "CANT_USE_CASH_COUPON");

		// 检查使用条件
		if (StringUtil.isEmpty(cashCouponDO.getConditions())) {
			return true;
		}

		// [{"period":30,"buy_amount":1000}]
		try {
			String errorCode = "";
			JSONArray conditions = (JSONArray) new JSONParser().parse(cashCouponDO.getConditions());
			for (int i = 0; i < conditions.size(); i++) {
				JSONObject condition = (JSONObject) conditions.get(i);
				errorCode = "";
				// 满N元?
				if (condition.containsKey("buy_amount")) {
					if (buyAmt.compareTo(new BigDecimal(condition.get("buy_amount").toString())) < 0) {
						errorCode = "BUY_AMOUNT_CONDITION_ERROR";
					}
				}
				// 满N天?
				if (condition.containsKey("period")) {
					if (financingTargetDO.getPeriod() < Integer.parseInt(condition.get("period").toString())) {
						errorCode = "PERIOD_CONDITION_ERROR";
					}
				}
				// 定标还是活标?
				if (condition.containsKey("target_type")) {
					if (!financingTargetDO.getType().equalsIgnoreCase(condition.get("target_type").toString())) {
						errorCode = "TARGET_TYPE_CONDITION_ERROR";
					}
				}

				if (StringUtil.isEmpty(errorCode)) {
					return true;
				}

			}

			if (StringUtil.isNotEmpty(errorCode)) {
				AssertUtil.assertFail(errorCode);
			}

		} catch (ParseException e) {
			LOG.error("现金券条件解释出错:" + cashCouponDO.getConditions(), e);
			return false;
		}

		return true;
	}

}
